﻿using Black.Minecraft.Editor.ViewModels.Core;
using Black.Minecraft.Editor.ViewModels.DataModels;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace Black.Minecraft.Editor.Views.DataViews
{
    /// <summary>
    /// DataView pour un emplacement de l'inventaire
    /// </summary>
    public partial class InventoryItemDataView : UserControl
    {
        #region Propriétés de dépendance

        public static readonly DependencyProperty DropCommandProperty = DependencyProperty.Register("DropCommand", typeof(ICommand), typeof(InventoryItemDataView), new PropertyMetadata(null));
        public static readonly DependencyProperty SelectionCommandProperty = DependencyProperty.Register("SelectionCommand", typeof(ICommand), typeof(InventoryItemDataView), new PropertyMetadata(null));
        public static readonly DependencyProperty SelectionCommandParameterProperty = DependencyProperty.Register("SelectionCommandParameter", typeof(object), typeof(InventoryItemDataView), new PropertyMetadata(null));
        public static readonly DependencyProperty SlotProperty = DependencyProperty.Register("Slot", typeof(SlotsEnum), typeof(InventoryItemDataView), new PropertyMetadata(SlotsEnum.None));

        #endregion

        #region Propriétés

        /// <summary>
        /// Obtient ou définit la propriété de dépendance DropCommand
        /// </summary>
        public ICommand DropCommand
        {
            get
            {
                return ((ICommand)this.GetValue(InventoryItemDataView.DropCommandProperty));
            }
            set
            {
                this.SetValue(InventoryItemDataView.DropCommandProperty, value);
            }
        }

        /// <summary>
        /// Obtient ou définit la propriété de dépendance SelectionCommand
        /// </summary>
        public ICommand SelectionCommand
        {
            get
            {
                return ((ICommand)this.GetValue(InventoryItemDataView.SelectionCommandProperty));
            }
            set
            {
                this.SetValue(InventoryItemDataView.SelectionCommandProperty, value);
            }
        }

        /// <summary>
        /// Obtient ou définit la propriété de dépendance SelectionCommandParameter
        /// </summary>
        public object SelectionCommandParameter
        {
            get
            {
                return (this.GetValue(InventoryItemDataView.SelectionCommandParameterProperty));
            }
            set
            {
                this.SetValue(InventoryItemDataView.SelectionCommandParameterProperty, value);
            }
        }

        /// <summary>
        /// Obtient ou définit la propriété de dépendance Slot
        /// </summary>
        public SlotsEnum Slot
        {
            get
            {
                return ((SlotsEnum)this.GetValue(InventoryItemDataView.SlotProperty));
            }
            set
            {
                this.SetValue(InventoryItemDataView.SlotProperty, value);
            }
        }

        #endregion

        #region Constructeurs

        /// <summary>
        /// Constructeur de la classe
        /// </summary>
        public InventoryItemDataView()
        {
            this.InitializeComponent();
        }

        #endregion

        #region Fonctions privées

        /// <summary>
        /// Se produit quand un drag est positionner au dessus
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void OnDragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent("ItemDataModel"))
            {
                ItemDataModel item = e.Data.GetData("ItemDataModel") as ItemDataModel;

                if ((this.Slot == SlotsEnum.Head && item.EquipmentType != EquipmentType.Head)
                    || (this.Slot == SlotsEnum.Chest && item.EquipmentType != EquipmentType.Chest)
                    || (this.Slot == SlotsEnum.Leg && item.EquipmentType != EquipmentType.Legs)
                    || (this.Slot == SlotsEnum.Feet && item.EquipmentType != EquipmentType.Feets))
                    e.Effects = DragDropEffects.None;
            }
            else
                e.Effects = DragDropEffects.None;
        }

        /// <summary>
        /// Se produit quand un drop est effectué
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void OnDrop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent("ItemDataModel"))
            {
                ItemDataModel item = e.Data.GetData("ItemDataModel") as ItemDataModel;

                // Vérification si placement authorisé

                if ((this.Slot == SlotsEnum.Head && item.EquipmentType != EquipmentType.Head)
                   || (this.Slot == SlotsEnum.Chest && item.EquipmentType != EquipmentType.Chest)
                   || (this.Slot == SlotsEnum.Leg && item.EquipmentType != EquipmentType.Legs)
                   || (this.Slot == SlotsEnum.Feet && item.EquipmentType != EquipmentType.Feets))
                {
                    MessageBox.Show("You cannot place this item here.", "Equipment place", MessageBoxButton.OK, MessageBoxImage.Information);
                    return;
                }

                // On déclenche le drop

                if (this.DropCommand != null)
                    this.DropCommand.Execute(new object[2] { item, this.Slot });
            }
        }

        /// <summary>
        /// Se produit sur un appuie sourie
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void OnMouseDown(object sender, MouseButtonEventArgs e)
        {
            if (this.SelectionCommand != null)
                this.SelectionCommand.Execute(this.SelectionCommandParameter);
        }

        #endregion
    }
}
